package com.nx.platform.es.biz.esspider.handler;


import com.nx.platform.es.biz.esspider.entity.Item;
import com.google.common.base.Enums;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.nx.platform.es.common.utils.MoreFunctions;
import com.nx.platform.es.common.utils.MoreMaps;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 指定integer(32位)中的8位，转成byte
 *
 * @author
 * @date 2018/04/24
 */
@HandlerDefine(HandlerType.SIMPLE)
public class SimpleIntegerToByteHandler extends AbstractSimpleHandler {

    private String field;
    private String toField;
    private BitRegion region;

    @Override
    public void init(Map<?, ?> settings) throws Exception {
        field = MoreMaps.getString(settings, "field");
        toField = MoreMaps.getString(settings, "toField");
        region = Enums.getIfPresent(BitRegion.class, MoreMaps.getString(settings, "region", "")).or(BitRegion.FF);
        Preconditions.checkArgument(!Strings.isNullOrEmpty(field), "field null or empty");
        if (Strings.isNullOrEmpty(toField)) {
            toField = field;
        }
    }

    @Override
    public void handle(Map<Long, Item> items) throws Exception {
        items.values().forEach((Item item) -> {
            Map<String, Object> doc = item.getDoc();
            Object oriValue = doc.get(field);
            if (oriValue != null) {
                Object b = null;
                if (oriValue instanceof Collection) {
                    Collection<?> c = (Collection) oriValue;
                    b = c.stream().map(MoreFunctions::objectToInteger)
                            .filter(Objects::nonNull)
                            .map(i -> (i & region.bit) >> region.right)
                            .filter(i -> i != 0)
                            .collect(Collectors.toList());
                } else {
                    Integer i = MoreFunctions.objectToInteger(oriValue);
                    if (i != null) {
                        b = (i & region.bit) >> region.right;
                    }
                }
                if (b != null) {
                    doc.put(toField, b);
                }
            }
        });
    }

    private enum BitRegion {

        FF(0xFF, 0), FF00(0xFF00, 8), FF0000(0xFF0000, 16), FF000000(0xFF000000, 24);

        private int bit;
        private int right;

        BitRegion(int bit, int right) {
            this.bit = bit;
            this.right = right;
        }

    }

}
